package sso.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import sso.util.JwtUtils;
import sso.util.WebUtils;
import java.util.*;


//认证服务的服务器
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
  //认证规则配置
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //1.关闭跨域攻击
        http.csrf().disable();
        //2.配置form 登陆认证
        http.formLogin()
                //登录成功怎么处理
                //.loginPage("/login.html")
                .successHandler(successHandler())
                //登录失败怎么处理
                .failureHandler(failureHandler());
        //对我们的登录的用户进行认证<没有认证就返回json提醒用户登录>
        http.exceptionHandling()  //entryPoint()使用这个就没有登陆就不能访问
                .authenticationEntryPoint(entryPoint());//提醒用户要认证
                //.accessDeniedHandler(null);

        //3.所有资源都得认证<这里放行所有的请求.不用认证anyRequest()>
        http.authorizeRequests()
                .anyRequest()
                .authenticated();

    }

    @Bean
   public BCryptPasswordEncoder passwordEncoder(){

       return new BCryptPasswordEncoder();
   }

   //认证成功后的处理器
   private AuthenticationSuccessHandler successHandler(){

        return (httpServletRequest,
                    httpServletResponse,
                   authentication ) -> {
            Map<String,Object> map=new HashMap<>();
            map.put("statis", 200);
            map.put("message", "欢迎登陆");
            Map<String,Object> jwtMap=new HashMap<>();
            //获取用户身份(包含了认证和授权信息)
            User principal = (User)authentication.getPrincipal();
            //获取用户名
            String username=principal.getUsername();
            //获取用户权限
            List<String> authoritiesList = new ArrayList<>();
            Collection<GrantedAuthority> authorities =
                    principal.getAuthorities();
            for(GrantedAuthority a:authorities){
                authoritiesList.add(a.getAuthority());//sys:res:create
            }
            jwtMap.put("username",username);
            jwtMap.put("authorities",authoritiesList);
            String token=JwtUtils.generatorToken(jwtMap);
            map.put("token",token);
            WebUtils.writeJsonToClient(httpServletResponse,map);
            };
        }

   //认证失败


  private AuthenticationFailureHandler failureHandler(){

        return (
                httpServletRequest,
                httpServletResponse,
                e) -> {
            Map<String,Object> map=new HashMap<>();
            map.put("statis", 500);
            map.put("message", "登陆失败");
            WebUtils.writeJsonToClient(httpServletResponse, map);
        };
   }
   //假如没有登陆的时候给出提示
    private AuthenticationEntryPoint entryPoint(){

        return (
                httpServletRequest,
                httpServletResponse,
                e) -> {
            Map<String,Object> map=new HashMap<>();
            map.put("statis", 501);
            map.put("message", "请先登陆");
            WebUtils.writeJsonToClient(httpServletResponse, map);
        };
   }


}
